package com.deepinjava.dbbmlite;

import kotlin.jvm.Throws;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.Callable;
import java.util.concurrent.CyclicBarrier;

import static com.deepinjava.dbbmlite.Application.THREAD_COUNT;
import static com.deepinjava.dbbmlite.BenchMod.*;
import static java.lang.Thread.sleep;

public class BenchTask implements Callable<Map<BenchMod, Long>> {


    protected int tid;
    protected Map<BenchMod, Long> recordmap;
    private BenchService benchService;
    private static CyclicBarrier cb;


    public BenchTask() {
        recordmap = new HashMap<>();
        cb = new CyclicBarrier(THREAD_COUNT);
    }

    public BenchTask(int tid){
        this();
        this.setTid(tid);
    }

    @Override
    public Map<BenchMod, Long> call() throws Exception {
        System.out.println("=====线程" + tid + "开始启动======");

        waitLock();
        runBench(ADD);

        waitLock(2);
        runBench(UPDATE);

        waitLock(1);
        runBench(READ);

//        waitLock(1);
//        runBench(EDIT);

        waitLock(1);
        runBench(PAGE);

        waitLock(1);
        runBench(WRITE);
//        runBench((tid % 2 == 0) ? READ : WRITE);
//        runBench((tid % 2 == 0) ? WRITE : READ);

        waitLock(1);
        runBench(COPY);

        waitLock(3);
        runBench(SUM);

        waitLock(3);
        runBench(FIND);

        waitLock(1);
        runBench(MATCH);

        waitLock(1);
        runBench(DEL);

        waitLock();

        System.out.println("=====线程" + tid + "执行结束======");
        return recordmap;
    }

    private void runBench(BenchMod benchMod) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        System.out.println("====线程T" + tid + "启动：" + benchMod);
        long startTime = System.currentTimeMillis();
        String n = benchMod.name().toLowerCase() + "Data";
        long c = -1;
        try {
            c = (long) benchService.getClass().getDeclaredMethod(n,int.class).invoke(benchService,tid);
        }catch (Exception e)
        {
            System.err.println("线程T"+tid+"执行"+ n + "异常：");
            e.printStackTrace();
        }

        long StopTime = System.currentTimeMillis();
        long TotalTime = StopTime - startTime;       //总消耗时间
        System.out.println("====线程" + tid + "执行" + benchMod +":" + c + "行；耗时" + TotalTime+"毫秒");
        recordmap.put(benchMod,TotalTime);
        System.out.println("====线程T" + tid + "结束：" + benchMod);
    }


    private void waitLock(int sleeptime) throws BrokenBarrierException, InterruptedException {
        sleep(sleeptime * 1000);
        waitLock();
    }
    private void waitLock() throws InterruptedException, BrokenBarrierException {
        cb.await();
        cb.reset();
    }


    public int getTid() {
        return tid;
    }

    public void setTid(int tid) {
        this.tid = tid;
//        record.put("tid", Long.valueOf(tid));
    }

    public BenchService getBenchService() {
        return benchService;
    }

    public void setBenchService(BenchService benchService) {
        this.benchService = benchService;
    }
}

